package com.group.yqxxb.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.group.yqxxb.builder.CheckSumBuilder;
import com.group.yqxxb.dao.MessageDao;
import com.group.yqxxb.dao.PicDao;
import com.group.yqxxb.pojo.*;
import com.group.yqxxb.response.R;
import com.group.yqxxb.service.MessageService;
import com.group.yqxxb.util.AliyunOSSClientUtil;
import org.apache.commons.io.IOUtils;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/message")
public class MessageController {
    public static final Logger logger = LoggerFactory.getLogger(TestController.class);

    @Autowired
    PicDao picDao;

    @Autowired
    MessageService messageService;

    @Autowired
    MessageDao messageDao;

    /**
     * 普通发送消息接口
     * */
    @PostMapping("/sendMsg")
    public R SendCommonMsg(@RequestBody Message message) throws Exception {
        JSONObject jsonObject = messageService.sendCommonMsg(message);
        R r = R.error();
        if(jsonObject.getInteger("code")==200){
            r.setCode(100);
            r.setMsg("发送成功");
        }else{
            r.setMsg("发送失败");
        }
        r.setData(jsonObject.getJSONObject("data").getString("timetag"));
        return r;
    }

    /**
     * 用户群发消息
     * */
    @PostMapping("/sendBatchMsg")
    public R senBatchMsg(@RequestBody SingleBatchMessage message)throws Exception{
        JSONObject jsonObject = messageService.sendBatchMsg(message);
        R r = R.error();
        if(jsonObject.getInteger("code")==200){
            if(!ObjectUtils.isEmpty(jsonObject.getString("unregister"))){
                r.setCode(100);
                r.setMsg("接口调用成功,但包含未注册用户:"+jsonObject.getString("unregister"));
            }else {
                r.setCode(100);
                r.setMsg("发送成功");
            }
        }else{
            r.setMsg("发送失败");
        }
        r.setData(jsonObject.getString("timetag"));
        return r;
    }

    /**
     * 用户撤回消息接口
     * */
    //有问题
    @PostMapping(value = "/recall",consumes = {"application/x-www-form-urlencoded;charset=UTF-8"})
    public R recallMsg(RecallMessage message) throws Exception{
        JSONObject jsonObject = messageService.recallMsg(message);
        R r = R.error();
        if(jsonObject.getInteger("code")==200){
                r.setCode(100);
                r.setMsg("撤回成功");
        }else{
            r.setMsg("撤回失败");
        }
        r.setData(jsonObject.getString("timetag"));
        return r;
    }

    /**
     * 用户单向删除消息接口
     * */
    @PostMapping(value = "/delMsgOneWay",consumes = {"application/x-www-form-urlencoded;charset=UTF-8"})
    public R deleteMsgOnOneWay(RecallMessage message) throws Exception{
        JSONObject jsonObject = messageService.recallMsg(message);
        R r = R.error();
        if(jsonObject.getInteger("code")==200){
            r.setCode(100);
            r.setMsg("删除成功");
        }else{
            r.setMsg("删除失败");
        }
        return r;
    }

    /**
     * 用户上传图片接口
     * */
    @PostMapping(value = "/picUpload")
    public R uploadFileToGoods(@Param("accId") String accId
            , @RequestParam("file") MultipartFile file) throws IOException {
        R r = new R(null);
        AliyunOSSClientUtil aliyunOSSClientUtil = new AliyunOSSClientUtil();
            Pic pic = new Pic();
            String url = aliyunOSSClientUtil.uploadFile(file,0);
            pic.setAccid(accId);
            pic.setUrl(url);
            picDao.addPicToDB(pic);
            r.setData(pic);
        return r;
    }


    /**
     * 用户单向删除消息接口
     * */
    @PostMapping("/querySessionMsg")
    public R getAgoMessage(AgoMessageRequest agoMessageRequest
                           /*@RequestParam("beginTime") String beginTime,
                           @RequestParam("endTime") String endTime,
                           @RequestParam("from")String from,
                           @RequestParam("to")String to,
                           @RequestParam("limit")Integer limit*/) throws Exception{
        //AgoMessageRequest agoMessageRequest = new AgoMessageRequest(beginTime,endTime,from,to,limit);
        List<AgoMessage> list= messageService.getAgoMessages(agoMessageRequest);
        R r = R.error();
        if(list.size()>0){
            r.setCode(100);
            r.setMsg("查询历史消息记录成功");
            r.setData(list);
        }else{
            r.setMsg("查询历史消息记录失败");
        }
        return r;
    }


    // 需要改成自身应用的appSecret
    private final String appSecret = "56cd93f549d8";

    /**
     * 发送消息后会自动回调，网易云信端会给我们发送post请求
     * 用来接收消息回调的结果，返回给前端
     * */
    @RequestMapping(value = {"/receiveMsg"}, method = {RequestMethod.POST})
    @ResponseBody
    public JSONObject mockClient(HttpServletRequest request) throws Exception {
        JSONObject result = new JSONObject();
        try {
            // 获取请求体
            byte[] body = readBody(request);
            if (body == null) {
                logger.warn("request wrong, empty body!");
                result.put("code", 414);
                return result;
            }
            // 获取部分request header，并打印
            String ContentType = request.getContentType();
            String AppKey = request.getHeader("AppKey");
            String CurTime = request.getHeader("CurTime");
            String MD5 = request.getHeader("MD5");
            String CheckSum = request.getHeader("CheckSum");
            logger.info("request headers: ContentType = {}, AppKey = {}, CurTime = {}, " +
                    "MD5 = {}, CheckSum = {}", ContentType, AppKey, CurTime, MD5, CheckSum);
            // 将请求体转成String格式，并打印
            String requestBody = new String(body, "utf-8");
            logger.info("request body = {}", requestBody);
            JSONObject jsonObject2 = JSONObject.parseObject(requestBody);
            System.out.println(jsonObject2);
            MessageResponse messageResponse = JSON.toJavaObject(jsonObject2,MessageResponse.class);
            if(messageResponse!=null){
                messageDao.insertIntoDB(messageResponse);
            }

            // 获取计算过的md5及checkSum
            String verifyMD5 = CheckSumBuilder.getMD5(requestBody);
            String verifyChecksum = CheckSumBuilder.getCheckSum(appSecret, verifyMD5, CurTime);
            logger.debug("verifyMD5 = {}, verifyChecksum = {}", verifyMD5, verifyChecksum);

            logger.info("校验成功，回调得到的结果是"+JSONObject.parseObject(requestBody));
            // TODO: 比较md5、checkSum是否一致，以及后续业务处理


            if(verifyMD5.equals(MD5)&&verifyChecksum.equals(verifyChecksum)){
                result.put("code", 200);
            }
            logger.info(result.toString());
            return result;
        } catch (Exception ex) {
            logger.error(ex.getMessage(),ex);
            result.put("code", 414);
            return result;
        }
    }


    private byte[] readBody(HttpServletRequest request) throws IOException {
        if (request.getContentLength() > 0) {
            byte[] body = new byte[request.getContentLength()];
            IOUtils.readFully(request.getInputStream(), body);
            return body;
        } else {
            return null;
        }
    }
}